package com.feonix.common.util;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DateUtil {

	protected static Log logger = LogFactory.getLog(DateUtil.class);
	public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
	public static final String YYYYMMDD_HHMMSS = "yyyyMMdd-HHmmss";
	public static final String YYYY_MM_DD = "yyyy-MM-dd";
	public static final String MM_DD = "MM-dd";
	public static final String HH_MM_SS = "HH:mm:ss";
	public static final String YYYY_MM = "yyyy-MM";
	public static final int SUB_YEAR = 1;
	public static final int SUB_MONTH = 2;
	public static final int SUB_DAY = 5;
	public static final int SUB_HOUR = 10;
	public static final int SUB_MINUTE = 12;
	public static final int SUB_SECOND = 13;
	static final String[] dayNames = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

	private static final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	/**
	 * 把符合日期格式的字符串转换为日期类型
	 * 
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public static Date stringtoDate(String dateStr, String format) {
		Date date = null;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		try {
			simpleDateFormat.setLenient(false);
			date = simpleDateFormat.parse(dateStr);
		} catch (Exception localException) {
			date = null;
		}
		return date;
	}

	/**
	 * 把符合日期格式的字符串转换为日期类型
	 * 
	 * @param dateStr
	 * @param format
	 * @param pos
	 * @return
	 */
	public static Date stringtoDate(String dateStr, String format, ParsePosition pos) {
		Date date = null;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		try {
			simpleDateFormat.setLenient(false);
			date = simpleDateFormat.parse(dateStr, pos);
		} catch (Exception localException) {
			date = null;
		}
		return date;
	}

	/**
	 * 把日期转换为字符串
	 * 
	 * @param date
	 * @param format
	 * @return
	 */
	public static String dateToString(Date date, String format) {
		String str = "";
		SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(format);
		localSimpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		try {
			str = localSimpleDateFormat.format(date);
		} catch (Exception localException) {
		}
		return str;
	}

	/**
	 * 将字符串转化成指定日期格式的字符串
	 * 
	 * @param strDate
	 * @param strStyle
	 * @return
	 */
	public static String formatDate(String strDate, String strStyle) {
		if ((StringUtil.isNotEmpty(strDate)) && (StringUtil.isNotEmpty(strStyle))) {
			Date date = stringtoDate(strDate, strStyle);
			if (date != null) {
				strDate = dateToString(date, strStyle);
			}
		}
		return strDate;
	}

	/**
	 * 获取当前时间的指定格式
	 * 
	 * @param format
	 * @return
	 */
	public static String getCurrDate(String format) {
		return dateToString(new Date(), format);
	}

	/**
	 * 
	 * @param dateKind
	 * @param dateStr
	 * @param amount
	 * @return
	 */
	public static String dateSub(int dateKind, String dateStr, int amount) {
		Date date = stringtoDate(dateStr, "yyyy-MM-dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(dateKind, amount);
		return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 两个日期相减
	 * 
	 * @param firstTime
	 * @param secTime
	 * @return
	 */
	public static long timeSub(String firstTime, String secTime) {
		long l1 = stringtoDate(firstTime, "yyyy-MM-dd HH:mm:ss").getTime();
		long l2 = stringtoDate(secTime, "yyyy-MM-dd HH:mm:ss").getTime();
		return ((l2 - l1) / 1000L);
	}

	/**
	 * 获得某月的天数
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getDaysOfMonth(String year, String month) {
		int i = 0;
		if ((month.equals("1")) || (month.equals("3")) || (month.equals("5")) || (month.equals("7"))
				|| (month.equals("8")) || (month.equals("10")) || (month.equals("12")))
			i = 31;
		else if ((month.equals("4")) || (month.equals("6")) || (month.equals("9")) || (month.equals("11"))) {
			i = 30;
		} else if (((Integer.parseInt(year) % 4 == 0) && (Integer.parseInt(year) % 100 != 0))
				|| (Integer.parseInt(year) % 400 == 0))
			i = 29;
		else {
			i = 28;
		}
		return i;
	}

	/**
	 * 获取某年某月的天数
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getDaysOfMonth(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1);
		return calendar.getActualMaximum(5);
	}

	/**
	 * 获得当前日期
	 * 
	 * @return
	 */
	public static int getToday() {
		Calendar calendar = Calendar.getInstance();
		return calendar.get(5);
	}

	/**
	 * 获得当前月份
	 * 
	 * @return
	 */
	public static int getToMonth() {
		Calendar calendar = Calendar.getInstance();
		return (calendar.get(2) + 1);
	}

	/**
	 * 获得当前年份
	 * 
	 * @return
	 */
	public static int getToYear() {
		Calendar calendar = Calendar.getInstance();
		return calendar.get(1);
	}

	/**
	 * 返回日期的天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(5);
	}

	/**
	 * 返回日期的年
	 * 
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(1);
	}

	/**
	 * 返回日期的月份，1-12
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return (calendar.get(2) + 1);
	}

	/**
	 * 计算两个日期相差的天数，如果date2 > date1 返回正数，否则返回负数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long dayDiff(Date date1, Date date2) {
		return ((date2.getTime() - date1.getTime()) / 86400000L);
	}

	/**
	 * 比较两个日期的年差
	 * 
	 * @param before
	 * @param after
	 * @return
	 */
	public static int yearDiff(String before, String after) {
		Date date1 = stringtoDate(before, "yyyy-MM-dd");
		Date date2 = stringtoDate(after, "yyyy-MM-dd");
		return (getYear(date2) - getYear(date1));
	}

	/**
	 * 比较指定日期与当前日期的差
	 * 
	 * @param after
	 * @return
	 */
	public static int yearDiffCurr(String after) {
		Date date1 = new Date();
		Date date2 = stringtoDate(after, "yyyy-MM-dd");
		return (getYear(date1) - getYear(date2));
	}

	/**
	 * 比较指定日期与当前日期的差
	 * 
	 * @param before
	 * @return
	 */
	public static long dayDiffCurr(String before) {
		Date date1 = stringtoDate(currDay(), "yyyy-MM-dd");
		Date date2 = stringtoDate(before, "yyyy-MM-dd");
		return ((date1.getTime() - date2.getTime()) / 86400000L);
	}

	/**
	 * 获取每月的第一周
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getFirstWeekdayOfMonth(int year, int month) {
		Calendar localCalendar = Calendar.getInstance();
		localCalendar.setFirstDayOfWeek(7);
		localCalendar.set(year, month - 1, 1);
		return localCalendar.get(7);
	}

	/**
	 * 获取每月的最后一周
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getLastWeekdayOfMonth(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(7);
		calendar.set(year, month - 1, getDaysOfMonth(year, month));
		return calendar.get(7);
	}

	/**
	 * 获得当前日期字符串，格式"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @return
	 */
	public static String getCurrDateTime() {
		Calendar calendar = Calendar.getInstance();
		return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 根据生日获取星座
	 * 
	 * @param birth
	 * @return
	 */
	public static String getAstro(String birth) {
		if (!(isDate(birth))) {
			birth = "2000" + birth;
		}
		if (!(isDate(birth))) {
			return "";
		}
		int i = Integer.parseInt(birth.substring(birth.indexOf("-") + 1, birth.lastIndexOf("-")));
		int j = Integer.parseInt(birth.substring(birth.lastIndexOf("-") + 1));
		String str = "魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯";
		int[] arrayOfInt = { 20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22 };
		int k = i * 2 - ((j < arrayOfInt[(i - 1)]) ? 2 : 0);
		return str.substring(k, k + 2) + "座";
	}

	/**
	 * 判断日期是否有效,包括闰年的情况
	 * 
	 * @param date
	 *            YYYY-mm-dd
	 * @return
	 */
	public static boolean isDate(String date) {
		StringBuffer stringBuffer = new StringBuffer("^((\\d{2}(([02468][048])|([13579][26]))-?((((0?");
		stringBuffer.append("[13578])|(1[02]))-?((0?[1-9])|([1-2][0-9])|(3[01])))");
		stringBuffer.append("|(((0?[469])|(11))-?((0?[1-9])|([1-2][0-9])|(30)))|");
		stringBuffer.append("(0?2-?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][12");
		stringBuffer.append("35679])|([13579][01345789]))-?((((0?[13578])|(1[02]))");
		stringBuffer.append("-?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))");
		stringBuffer.append("-?((0?[1-9])|([1-2][0-9])|(30)))|(0?2-?((0?[");
		stringBuffer.append("1-9])|(1[0-9])|(2[0-8]))))))");
		Pattern pattern = Pattern.compile(stringBuffer.toString());
		return pattern.matcher(date).matches();
	}

	/**
	 * 取得指定日期过 months 月后的日期 (当 months 为负数表示指定月之前);
	 * 
	 * @param date
	 * @param months
	 * @return
	 */
	public static Date nextMonth(Date date, int months) {
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		calendar.add(2, months);
		return calendar.getTime();
	}

	/**
	 * 取得指定日期过 day 天后的日期 (当 day 为负数表示指日期之前);
	 * 
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date nextDay(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		calendar.add(6, day);
		return calendar.getTime();
	}

	/**
	 * 取得距离今天 day 日的日期
	 * 
	 * @param day
	 * @param format
	 * @return
	 */
	public static String nextDay(int day, String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(6, day);
		return dateToString(calendar.getTime(), format);
	}

	/**
	 * 取得指定日期过 day 周后的日期 (当 day 为负数表示指定月之前)
	 * 
	 * @param date
	 *            日期 为null时表示当天
	 * @param week
	 * @return
	 */
	public static Date nextWeek(Date date, int week) {
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		calendar.add(4, week);
		return calendar.getTime();
	}

	/**
	 * 获取当前的日期(yyyy-MM-dd)
	 * 
	 * @return
	 */
	public static String currDay() {
		return dateToString(new Date(), "yyyy-MM-dd");
	}

	/**
	 * 获取昨天的日期
	 * 
	 * @param paramInt
	 * @return
	 */
	public static String befoDay(int paramInt) {
		return befoDay(paramInt, "yyyy-MM-dd");
	}

	/**
	 * 根据时间类型获取昨天的日期
	 * 
	 * @param day
	 * @param format
	 * @return
	 */
	public static String befoDay(int day, String format) {
		return dateToString(nextDay(new Date(), -day), format);
	}

	/**
	 * 获取明天的日期
	 * 
	 * @return
	 */
	public static String afterDay() {
		return dateToString(nextDay(new Date(), 1), "yyyy-MM-dd");
	}

	/**
	 * 取得当前时间距离1900/1/1的天数
	 * 
	 * @return
	 */
	public static int getDayNum() {
		int i = 0;
		GregorianCalendar gregorianCalendar1 = new GregorianCalendar();
		Date date1 = gregorianCalendar1.getTime();
		GregorianCalendar gregorianCalendar2 = new GregorianCalendar(1900, 1, 1);
		Date date2 = gregorianCalendar2.getTime();
		i = (int) ((date1.getTime() - date2.getTime()) / 86400000L);
		return i;
	}

	/**
	 * getDayNum的逆方法(用于处理Excel取出的日期格式数据等)
	 * 
	 * @param day
	 * @return
	 */
	public static Date getDateByNum(int day) {
		GregorianCalendar gregorianCalendar = new GregorianCalendar(1900, 1, 1);
		Date date = gregorianCalendar.getTime();
		date = nextDay(date, day);
		return date;
	}

	/**
	 * 针对yyyy-MM-dd HH:mm:ss格式,显示yyyymmdd
	 * 
	 * @param datestr
	 * @return
	 */
	public static String getYmdDateCN(String datestr) {
		if (datestr == null)
			return "";
		if (datestr.length() < 10)
			return "";
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(datestr.substring(0, 4)).append(datestr.substring(5, 7)).append(datestr.substring(8, 10));
		return stringBuffer.toString();
	}

	/**
	 * 获取本月第一天
	 * 
	 * @param format
	 * @return
	 */
	public static String getFirstDayOfMonth(String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(5, 1);
		return dateToString(calendar.getTime(), format);
	}

	/**
	 * 获取本月最后一天
	 * 
	 * @param format
	 * @return
	 */
	public static String getLastDayOfMonth(String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(5, 1);
		calendar.add(2, 1);
		calendar.add(5, -1);
		return dateToString(calendar.getTime(), format);
	}

}
